using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;

namespace eTMS.Controls
{
    public class DataGridView : System.Windows.Forms.DataGridView
    {
        private Color endgradColor = Color.FromArgb(220, 220, 230);
        private Color startgradColor = Color.FromArgb(220, 230, 240);
        private LinearGradientMode gradientMode = LinearGradientMode.Vertical;
        private List<int> lsColumnsMerge = new List<int>();
        private List<int> lsRowsMerge = new List<int>();
        private List<DataGridViewColumnHeaderCell> lsCellMerged = new List<DataGridViewColumnHeaderCell>();
        private float gradPercent = 0.5f;
        public bool IsBlend = false;
        public LinearGradientMode GradientMode
        {
            get
            {
                return gradientMode;
            }
            set
            {
                gradientMode = value;
                this.Invalidate();
            }
        }
        public float GradientPercent
        {
            get
            {
                return gradPercent;
            }
            set
            {
                gradPercent = value;
                this.Invalidate();
            }
        }
        public Color StartGradientColor
        {
            get
            {
                return startgradColor;
            }
            set
            {
                startgradColor = value;
                this.Invalidate();
            }
        }
        public Color EndGradientColor
        {
            get
            {
                return endgradColor;
            }
            set
            {
                endgradColor = value;
                this.Invalidate();
            }
        }
        public DataGridView()
        {
            this.BackColor = Color.FromArgb(255, 255, 255);
            this.StartGradientColor = Color.FromArgb(240, 245, 255);
            this.EndGradientColor = Color.FromArgb(219, 226, 237);
            SetStyle(System.Windows.Forms.ControlStyles.AllPaintingInWmPaint | System.Windows.Forms.ControlStyles.OptimizedDoubleBuffer, true);
            this.GridColor = Color.FromArgb(150, 160, 225);
            //this.autosc
        }
        protected override void OnCellPainting(System.Windows.Forms.DataGridViewCellPaintingEventArgs e)
        {
            bool found = true;
            if (e.RowIndex == -1)
            {
                foreach (DataGridViewColumnHeaderCell cell in lsCellMerged)
                {
                    if (cell.ColumnIndex == e.ColumnIndex)
                    {
                        found = false;
                        break;
                    }
                }
            }
            if ((e.ColumnIndex == -1) || (found && (e.RowIndex == -1)))
            {
                DrawBackGroundHeaders(e);
                e.Handled = true;
            }
            else
            {
                base.OnCellPainting(e);
                string key = e.ColumnIndex.ToString() + "_" + e.RowIndex.ToString();
                if (dicContent.ContainsKey(key))
                {
                    Rectangle r = new Rectangle(3, 3, e.CellBounds.Width - 6, e.CellBounds.Height - 6);
                    SolidBrush br = new SolidBrush(dicContent[key].BackGroundColor);
                    e.Graphics.FillRectangle(br, r);
                    br.Dispose();
                    e.Graphics.DrawRectangle(Pens.Magenta, r);
                    br = new SolidBrush(dicContent[key].BackGroundColor);
                    StringFormat ftm = new StringFormat();
                    ftm.Alignment = StringAlignment.Center;
                    ftm.LineAlignment = StringAlignment.Center;
                    Rectangle rc = new Rectangle(5, 5, r.Width - 6, 20);
                    e.Graphics.DrawString(dicContent[key].Title, new Font(this.Font, FontStyle.Bold), br, rc, ftm);
                    br.Dispose();

                    br = new SolidBrush(dicContent[key].TextColor);
                    rc = new Rectangle(5, 26, r.Width - 6, r.Height - 30);
                    e.Graphics.DrawString(dicContent[key].Content, new Font(this.Font, FontStyle.Bold), br, rc, ftm);
                    br.Dispose();
                }
                e.Handled = false;
            }
        }
        private bool CompareToRow(List<int> lsMaster, int rowIndex1, int rowIndex2)
        {
            foreach (int indexCol in lsMaster)
            {
                if (Convert.ToString(this.Rows[rowIndex1].Cells[indexCol].Value) != Convert.ToString(this.Rows[rowIndex2].Cells[indexCol].Value))
                    return false;
            }
            return true;
        }
        public void DoMerge()
        {
            this.AllowUserToResizeRows = false;
            lsCellMerged.Clear();
            foreach (int indexCol in lsColumnsMerge)
            {
                if (indexCol >= 0)
                {
                    for (int i = 0; i < this.RowCount - 1; i++)
                    {
                        int i1 = i;
                        while (CompareToRow(dicMergeColumnsValues[indexCol], i, i + 1))
                        {
                            i++;
                            if (i == this.RowCount - 1) break;
                        }
                        if (i1 != i)
                        {
                            for (int ic = i1; ic <= i; ic++)
                            {

                                DataGridViewCell mergeCell = null;
                                if (this.Columns[indexCol] is DataGridViewTextBoxColumn)
                                {
                                    mergeCell = new VMergedGridViewTextBoxCell();
                                    ((VMergedGridViewTextBoxCell)mergeCell).TopRow = i1;
                                    ((VMergedGridViewTextBoxCell)mergeCell).BottomRow = i;
                                }
                                else if (this.Columns[indexCol] is DataGridViewCheckBoxColumn)
                                {
                                    mergeCell = new VMergedGridViewCheckBoxCell();
                                    ((VMergedGridViewCheckBoxCell)mergeCell).TopRow = i1;
                                    ((VMergedGridViewCheckBoxCell)mergeCell).BottomRow = i;
                                }
                                CopyMergeProperties(this.Rows[ic].Cells[indexCol], mergeCell);
                                this.Rows[ic].Cells[indexCol] = mergeCell;
                            }
                        }
                    }
                }
                else
                {
                }
            }
            foreach (int indexCol in lsRowsMerge)
            {
                if (indexCol >= 0)
                {
                    for (int i = 0; i < this.ColumnCount - 1; i++)
                    {
                        int i1 = i;
                        while (Convert.ToString(this.Rows[indexCol].Cells[i].Value) == Convert.ToString(this.Rows[indexCol].Cells[i + 1].Value))
                        {
                            i++;
                            if (i == this.ColumnCount - 1) break;
                        }
                        if (i1 != i)
                        {
                            for (int ic = i1; ic <= i; ic++)
                            {
                                HMergedGridViewTextBoxCell mergeCell = new HMergedGridViewTextBoxCell();
                                mergeCell.LeftColumn = i1;
                                mergeCell.RightColumn = i;
                                CopyMergeProperties(this.Rows[indexCol].Cells[ic], mergeCell);
                                this.Rows[indexCol].Cells[ic] = mergeCell;
                            }
                        }
                    }
                }
                else
                {
                    for (int i = 0; i < this.ColumnCount - 1; i++)
                    {
                        int i1 = i;
                        while (this.Columns[i].HeaderText.ToString() == this.Columns[i + 1].HeaderText.ToString())
                        {
                            i++;
                            if (i == this.ColumnCount - 1) break;
                        }
                        if (i1 != i)
                        {
                            for (int ic = i1; ic <= i; ic++)
                            {
                                HeaderMergedGridViewTextBoxCell mergeCell = new HeaderMergedGridViewTextBoxCell();
                                mergeCell.LeftColumn = i1;
                                mergeCell.RightColumn = i;
                                CopyMergeProperties(this.Columns[ic].HeaderCell, mergeCell);
                                //mergeCell.Value = this.Columns[ic].HeaderCell.Value;
                                //mergeCell.Style = this.Columns[ic].HeaderCell.Style;
                                //mergeCell.ToolTipText = this.Columns[ic].HeaderCell.ToolTipText;
                                this.Columns[ic].HeaderCell = mergeCell;
                                lsCellMerged.Add(mergeCell);
                            }
                        }
                    }
                }
            }
        }
        private void CopyMergeProperties(DataGridViewCell source, DataGridViewCell des)
        {
            des.Value = source.Value;
            des.Style = source.Style;
            des.ToolTipText = source.ToolTipText;
            if (!(source is DataGridViewColumnHeaderCell))
            {
                try
                {
                    des.ReadOnly = source.ReadOnly;
                }
                catch
                {
                }
            }
        }
        protected override void OnSelectionChanged(EventArgs e)
        {
            base.OnSelectionChanged(e);
            for (int i = -1; i < this.ColumnCount; i++)
            {
                this.InvalidateCell(i, -1);
            }
            for (int i = 0; i < this.RowCount; i++)
            {
                this.InvalidateCell(-1, i);
            }
            foreach (int i in this.lsRowsMerge)
            {
                if (i >= 0)
                {
                    if (this.Rows.Count > i)
                        this.InvalidateRow(i);
                }
            }
            foreach (int i in this.lsColumnsMerge)
            {
                if (i >= 0)
                {
                    this.InvalidateColumn(i);
                }
            }

        }
        private void DrawBackGroundHeaders(System.Windows.Forms.DataGridViewCellPaintingEventArgs e)
        {
            // Create a rectangle
            //Rectangle rect = this.ClientRectangle;
            // Create a linear gradient brush
            Graphics g = e.Graphics;
            Rectangle rect = e.CellBounds;
            SolidBrush br = new SolidBrush(Color.White);
            g.FillRectangle(br, rect);
            br.Dispose();
            Pen p = null;
            Brush rgBrush = null;
            List<int> lsRowSelected = new List<int>();
            bool selectedRow = false;
            bool selectedCol = false;
            foreach (System.Windows.Forms.DataGridViewCell cell in this.SelectedCells)
            {
                lsRowSelected.Add(cell.RowIndex);
            }
            List<int> ls = new List<int>();
            foreach (System.Windows.Forms.DataGridViewCell cell in this.SelectedCells)
            {
                ls.Add(cell.ColumnIndex);
            }
            if (lsRowSelected.Contains(e.RowIndex) && !(this.SelectionMode == System.Windows.Forms.DataGridViewSelectionMode.FullColumnSelect))
            {
                selectedRow = true;
                rgBrush = new LinearGradientBrush(
                rect, Color.FromArgb(248, 215, 151), Color.FromArgb(230, 241, 193, 95), gradientMode
                );
                ((LinearGradientBrush)rgBrush).SetSigmaBellShape(0.2f, 1);
            }
            else if (ls.Contains(e.ColumnIndex) && !(this.SelectionMode == System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect))
            {
                selectedCol = true;
                rgBrush = new LinearGradientBrush(
                rect, Color.FromArgb(248, 215, 151), Color.FromArgb(230, 241, 193, 95), gradientMode
                );
                ((LinearGradientBrush)rgBrush).SetSigmaBellShape(0.2f, 1);
            }
            else if (e.ColumnIndex == -1)
            {
                if (e.RowIndex == -1)
                {
                    rgBrush = new SolidBrush(Color.FromArgb(169, 196, 233));
                }
                else
                {
                    rgBrush = new LinearGradientBrush(
                    rect, this.startgradColor, this.startgradColor, gradientMode
                    );
                }
            }
            else
            {
                rgBrush = new LinearGradientBrush(
                   rect, this.startgradColor, this.endgradColor, gradientMode
                );
            }
            // Set signma bell shape
            //rgBrush.SetSigmaBellShape(gradPercent, 1.0f);
            // Fill rectangle again
            g.FillRectangle(rgBrush, rect);
            // Dispose of object

            e.PaintContent(e.ClipBounds);

            GraphicsPath gph = new GraphicsPath();
            if (selectedCol || selectedRow)
            {
                p = new Pen(Color.FromArgb(241, 180, 86));
            }
            else
            {
                p = new Pen(this.GridColor);
            }
            if (e.ColumnIndex == -1)
            {
                if (e.RowIndex == -1)
                {
                    gph.AddLine(rect.X, rect.Y, rect.X + rect.Width - 1, rect.Y);
                    gph.AddLine(rect.X + rect.Width - 1, rect.Y, rect.X + rect.Width - 1, rect.Y + rect.Height - 1);
                    gph.AddLine(rect.X + rect.Width - 1, rect.Y + rect.Height - 1, rect.X, rect.Y + rect.Height - 1);
                    gph.AddLine(rect.X, rect.Y + rect.Height - 1, rect.X, rect.Y);
                }
                else
                {
                    if (selectedRow)
                    {
                        gph.AddLine(rect.X, rect.Y + rect.Height - 1, rect.X, rect.Y);
                        gph.AddLine(rect.X, rect.Y - 1, rect.X + rect.Width - 1, rect.Y - 1);
                    }
                    gph.AddLine(rect.X + rect.Width - 1, rect.Y, rect.X + rect.Width - 1, rect.Y + rect.Height - 1);
                    gph.AddLine(rect.X + rect.Width - 1, rect.Y + rect.Height - 1, rect.X, rect.Y + rect.Height - 1);
                }
            }
            else
            {
                if (selectedCol)
                {
                    gph.AddLine(rect.X - 1, rect.Y + rect.Height - 1, rect.X - 1, rect.Y);
                    gph.AddLine(rect.X, rect.Y, rect.X + rect.Width - 1, rect.Y);
                }
                gph.AddLine(rect.X + rect.Width - 1, rect.Y, rect.X + rect.Width - 1, rect.Y + rect.Height - 1);
                gph.AddLine(rect.X + rect.Width - 1, rect.Y + rect.Height - 1, rect.X, rect.Y + rect.Height - 1);
            }
            g.DrawPath(p, gph);
            p.Dispose();
        }
        Dictionary<int, List<int>> dicMergeColumnsValues = new Dictionary<int, List<int>>();
        public void AllowMergeColumn(int ColumnIndex, bool allow)
        {
            if (allow)
            {
                if (!lsColumnsMerge.Contains(ColumnIndex))
                {
                    lsColumnsMerge.Add(ColumnIndex);
                    List<int> ls = new List<int>();
                    ls.Add(ColumnIndex);
                    dicMergeColumnsValues.Add(ColumnIndex, ls);
                }
            }
            else
            {
                lsColumnsMerge.Remove(ColumnIndex);
                dicMergeColumnsValues.Remove(ColumnIndex);
            }
        }
        public void AllowMergeColumn(int ColumnIndex, params int[] ColumnMasters)
        {
            if (!lsColumnsMerge.Contains(ColumnIndex))
            {
                lsColumnsMerge.Add(ColumnIndex);
                dicMergeColumnsValues.Add(ColumnIndex, new List<int>(ColumnMasters));
            }
        }
        public void AllowMergeRow(int RowIndex, bool allow)
        {
            if (allow)
            {
                if (!lsRowsMerge.Contains(RowIndex))
                {
                    lsRowsMerge.Add(RowIndex);
                }
            }
            else
            {
                lsRowsMerge.Remove(RowIndex);
            }
        }
        public void ConvertRowToHeader(int row)
        {
            for (int i = 0; i < this.ColumnCount; i++)
            {
                if (this.Rows[row].Cells[i] is HMergedGridViewTextBoxCell)
                {
                    ((HMergedGridViewTextBoxCell)this.Rows[row].Cells[i]).IsGrad = true;
                }
                else if (this.Rows[row].Cells[i] is VMergedGridViewTextBoxCell)
                {
                    ((VMergedGridViewTextBoxCell)this.Rows[row].Cells[i]).IsGrad = true;
                }
                else if (this.Rows[row].Cells[i] is DataGridViewTextBoxCell)
                {
                    GradDataGridViewTextBoxCell cell = new GradDataGridViewTextBoxCell();
                    CopyMergeProperties(this.Rows[row].Cells[i], cell);
                    this.Rows[row].Cells[i] = cell;
                    cell.ReadOnly = true;
                }
            }
            this.Rows[row].Frozen = true;
        }
        private int roundPercent = 0;
        public int RoundPercent
        {
            get
            {
                return roundPercent;
            }
            set
            {
                roundPercent = value;
            }
        }
        protected override void OnSorted(EventArgs e)
        {
            base.OnSorted(e);
            this.DoMerge();
        }
        private bool isInnerChanged = false;
        protected override void OnCellEndEdit(DataGridViewCellEventArgs e)
        {
            base.OnCellEndEdit(e);
            if (isInnerChanged) return;
            isInnerChanged = true;
            if (this[e.ColumnIndex, e.RowIndex] is HMergedGridViewTextBoxCell)
            {
                HMergedGridViewTextBoxCell cell = (HMergedGridViewTextBoxCell)this[e.ColumnIndex, e.RowIndex];
                for (int i = cell.LeftColumn; i <= cell.RightColumn; i++)
                {
                    this[i, e.RowIndex].Value = this[e.ColumnIndex, e.RowIndex].Value;
                    this.InvalidateCell(i, e.RowIndex);
                }
            }
            else if (this[e.ColumnIndex, e.RowIndex] is VMergedGridViewCheckBoxCell)
            {
                VMergedGridViewCheckBoxCell cell = (VMergedGridViewCheckBoxCell)this[e.ColumnIndex, e.RowIndex];
                for (int i = cell.TopRow; i <= cell.BottomRow; i++)
                {
                    this[e.ColumnIndex, i].Value = this[e.ColumnIndex, e.RowIndex].Value;
                    this.InvalidateCell(e.ColumnIndex, i);
                }
            }
            else if (this[e.ColumnIndex, e.RowIndex] is VMergedGridViewTextBoxCell)
            {
                VMergedGridViewTextBoxCell cell = (VMergedGridViewTextBoxCell)this[e.ColumnIndex, e.RowIndex];
                for (int i = cell.TopRow; i <= cell.BottomRow; i++)
                {
                    this[e.ColumnIndex, i].Value = this[e.ColumnIndex, e.RowIndex].Value;
                    this.InvalidateCell(e.ColumnIndex, i);
                }
            }
            isInnerChanged = false;
        }
        protected override void OnCellContentClick(DataGridViewCellEventArgs e)
        {
            base.OnCellContentClick(e);
            this.InvalidateCell(e.ColumnIndex, e.RowIndex);
        }
        private Dictionary<string, GridNodeItem> dicContent = new Dictionary<string, GridNodeItem>();
        public void AddContent(int col, int row, GridNodeItem item)
        {
            string key = col.ToString() + "_" + row.ToString();
            if (!dicContent.ContainsKey(key))
            {
                dicContent.Add(key, item);
            }
            else
            {
                dicContent[key] = item;
            }
        }
        public void RemoveContent(int col, int row)
        {
            string key = col.ToString() + "_" + row.ToString();
            dicContent.Remove(key);
        }
        public void SwapContent(int srcCol, int srcRow, int desCol, int desRow)
        {
            string key1 = srcCol.ToString() + "_" + srcRow.ToString();
            string key2 = srcCol.ToString() + "_" + srcRow.ToString();
            if (dicContent.ContainsKey(key1))
            {
                if (!dicContent.ContainsKey(key2))
                {
                    dicContent.Add(key2, dicContent[key1]);
                    dicContent.Remove(key1);
                }
                else
                {
                    GridNodeItem item = dicContent[key2];
                    dicContent[key2] = dicContent[key1];
                    dicContent[key1] = item;
                }
            }
            else
            {
                if (dicContent.ContainsKey(key1))
                {
                    dicContent.Add(key1, dicContent[key2]);
                    dicContent.Remove(key2);
                }
            }
        }
    }
    public class HMergedGridViewTextBoxCell : DataGridViewTextBoxCell
    {
        private int m_nLeftColumn = 0;
        private int m_nRightColumn = 0;
        public bool IsGrad = false;
        /// <summary>
        /// Column Index of the left-most cell to be merged.
        /// This cell controls the merged text.
        /// </summary>
        public int LeftColumn
        {
            get
            {
                return m_nLeftColumn;
            }
            set
            {
                m_nLeftColumn = value;
            }
        }

        /// <summary>
        /// Column Index of the right-most cell to be merged
        /// </summary>
        public int RightColumn
        {
            get
            {
                return m_nRightColumn;
            }
            set
            {
                m_nRightColumn = value;
            }
        }

        protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
        {
            try
            {
                int mergeindex = ColumnIndex - m_nLeftColumn;
                int i;
                int nWidth;
                int nWidthLeft;
                string strText;
                bool selected = false;
                DataGridViewCellStyle style = this.HasStyle ? this.InheritedStyle : this.Style;
                foreach (DataGridViewCell cell in this.DataGridView.SelectedCells)
                {
                    if ((cell.RowIndex == this.RowIndex) && (cell.ColumnIndex >= m_nLeftColumn) && (cell.ColumnIndex <= m_nRightColumn))
                    {
                        selected = true;
                        break;
                    }
                }
                // Draw the text
                RectangleF rectDest = RectangleF.Empty;
                // Determine the total width of the merged cell
                nWidth = 0;
                for (i = m_nLeftColumn; i <= m_nRightColumn; i++)
                    nWidth += this.OwningRow.Cells[i].Size.Width;

                // Determine the width before the current cell.
                nWidthLeft = 0;
                for (i = m_nLeftColumn; i < ColumnIndex; i++)
                    nWidthLeft += this.OwningRow.Cells[i].Size.Width;
                if (!IsGrad)
                {
                    if (!selected)
                    {
                        graphics.FillRectangle(new SolidBrush(style.BackColor), cellBounds);
                    }
                    else
                    {
                        graphics.FillRectangle(new SolidBrush(style.SelectionBackColor), cellBounds);
                    }
                }
                else
                {
                    GradContentPainter.DrawBackGroundHeaders(graphics, new Rectangle(cellBounds.Left - nWidthLeft, cellBounds.Top, nWidth, cellBounds.Height - 1));
                }
                // Draw the separator for rows
                graphics.DrawLine(new Pen(new SolidBrush(this.DataGridView.GridColor)), cellBounds.Left, cellBounds.Bottom - 1, cellBounds.Right, cellBounds.Bottom - 1);


                // Retrieve the text to be displayed
                if (this.InheritedStyle.Format != "")
                {
                    strText = string.Format("{0:" + this.InheritedStyle.Format + "}", this.OwningRow.Cells[this.ColumnIndex].Value);
                }
                else if (this.Style.Format != "")
                {
                    strText = string.Format("{0:" + this.Style.Format + "}", this.OwningRow.Cells[this.ColumnIndex].Value);
                }
                else
                {
                    strText = this.OwningRow.Cells[this.ColumnIndex].Value.ToString();
                }

                rectDest = new RectangleF(cellBounds.Left - nWidthLeft, cellBounds.Top, nWidth, cellBounds.Height);

                GradContentPainter.DrawContent(graphics, style, cellBounds, rectDest, strText, selected);



                // Draw the right vertical line for the cell
                if (ColumnIndex == m_nRightColumn)
                {
                    graphics.DrawLine(new Pen(new SolidBrush(this.DataGridView.GridColor)), cellBounds.Right - 1, cellBounds.Top, cellBounds.Right - 1, cellBounds.Bottom);
                    //graphics.DrawLine(new Pen(new SolidBrush(this.DataGridView.GridColor)), cellBounds.Right, cellBounds.Height, cellBounds.Right - nWidth, cellBounds.Height);
                }



            }
            catch
            {
                //Trace.WriteLine(ex.ToString());
            }
        }



    }// class
    public class VMergedGridViewTextBoxCell : DataGridViewTextBoxCell
    {
        public bool IsGrad = false;
        private int m_nTopRow = 0;
        private int m_nBottomRow = 0;

        /// <summary>
        /// Column Index of the left-most cell to be merged.
        /// This cell controls the merged text.
        /// </summary>
        public int TopRow
        {
            get
            {
                return m_nTopRow;
            }
            set
            {
                m_nTopRow = value;
            }
        }

        /// <summary>
        /// Column Index of the right-most cell to be merged
        /// </summary>
        public int BottomRow
        {
            get
            {
                return m_nBottomRow;
            }
            set
            {
                m_nBottomRow = value;
            }
        }

        protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
        {
            try
            {
                int mergeindex = RowIndex - m_nTopRow;
                int i;
                int nHeight;
                int nHeightTop;
                string strText;
                bool selected = false;

                DataGridViewCellStyle style = this.HasStyle ? this.InheritedStyle : this.Style;
                foreach (DataGridViewCell cell in this.DataGridView.SelectedCells)
                {
                    if ((cell.ColumnIndex == this.ColumnIndex) && (cell.RowIndex >= m_nTopRow) && (cell.RowIndex <= m_nBottomRow))
                    {
                        selected = true;
                        break;
                    }
                }
                if ((!selected) && !IsGrad)
                {
                    graphics.FillRectangle(new SolidBrush(style.BackColor), cellBounds);
                }
                else
                {
                    if (!this.Frozen)
                    {
                        graphics.FillRectangle(new SolidBrush(style.SelectionBackColor), cellBounds);
                    }
                    else
                    {
                        GradContentPainter.DrawBackGroundHeaders(graphics, cellBounds);
                    }
                }// Draw the separator for rows
                graphics.DrawLine(new Pen(new SolidBrush(this.DataGridView.GridColor)), cellBounds.Right - 1, cellBounds.Top, cellBounds.Right - 1, cellBounds.Bottom);

                // Draw the right vertical line for the cell
                if (RowIndex == m_nBottomRow)
                    graphics.DrawLine(new Pen(new SolidBrush(this.DataGridView.GridColor)), cellBounds.Left, cellBounds.Bottom - 1, cellBounds.Right, cellBounds.Bottom - 1);
                // Draw the text
                RectangleF rectDest = RectangleF.Empty;

                // Determine the total width of the merged cell
                nHeight = 0;
                for (i = m_nTopRow; i <= m_nBottomRow; i++)
                    nHeight += this.DataGridView.Rows[i].Cells[this.ColumnIndex].Size.Height;

                // Determine the width before the current cell.
                nHeightTop = 0;
                for (i = m_nTopRow; i < RowIndex; i++)
                    nHeightTop += this.DataGridView.Rows[i].Cells[this.ColumnIndex].Size.Height;

                // Retrieve the text to be displayed
                strText = "";
                if (this.InheritedStyle.Format != "")
                {
                    strText = string.Format("{0:" + this.InheritedStyle.Format + "}", this.OwningRow.Cells[this.ColumnIndex].Value);
                }
                else if (this.Style.Format != "")
                {
                    strText = string.Format("{0:" + this.Style.Format + "}", this.OwningRow.Cells[this.ColumnIndex].Value);
                }
                else
                {
                    strText = this.OwningRow.Cells[this.ColumnIndex].Value.ToString();
                }
                rectDest = new RectangleF(cellBounds.Left, cellBounds.Top - nHeightTop, cellBounds.Width, nHeight);
                GradContentPainter.DrawContent(graphics, style, cellBounds, rectDest, strText, selected);
            }
            catch
            {

            }
        }

    }
    public class VMergedGridViewCheckBoxCell : DataGridViewCheckBoxCell
    {
        public bool IsGrad = false;
        private int m_nTopRow = 0;
        private int m_nBottomRow = 0;

        /// <summary>
        /// Column Index of the left-most cell to be merged.
        /// This cell controls the merged text.
        /// </summary>
        public int TopRow
        {
            get
            {
                return m_nTopRow;
            }
            set
            {
                m_nTopRow = value;
            }
        }

        /// <summary>
        /// Column Index of the right-most cell to be merged
        /// </summary>
        public int BottomRow
        {
            get
            {
                return m_nBottomRow;
            }
            set
            {
                m_nBottomRow = value;
            }
        }


        protected override Rectangle GetContentBounds(Graphics graphics, DataGridViewCellStyle cellStyle, int rowIndex)
        {
            Rectangle r = base.GetContentBounds(graphics, cellStyle, rowIndex);
            int nHeight = 0;
            int nHeightTop = 0;
            for (int i = m_nTopRow; i <= m_nBottomRow; i++)
                nHeight += this.DataGridView.Rows[i].Cells[this.ColumnIndex].Size.Height;
            for (int i = m_nTopRow; i < this.RowIndex; i++)
                nHeightTop += this.DataGridView.Rows[i].Cells[this.ColumnIndex].Size.Height;
            Rectangle rect = new Rectangle(r.Left, nHeight / 2 - nHeightTop - r.Top, r.Width, r.Height);
            return rect;
        }
        protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
        {
            try
            {
                int mergeindex = RowIndex - m_nTopRow;
                int i;
                int nHeight;
                int nHeightTop;
                string strText;
                bool selected = false;
                DataGridViewCellStyle style = this.HasStyle ? this.InheritedStyle : this.Style;
                foreach (DataGridViewCell cell in this.DataGridView.SelectedCells)
                {
                    if ((cell.ColumnIndex == this.ColumnIndex) && (cell.RowIndex >= m_nTopRow) && (cell.RowIndex <= m_nBottomRow))
                    {
                        selected = true;
                        break;
                    }
                }
                nHeight = 0;
                for (i = m_nTopRow; i <= m_nBottomRow; i++)
                    nHeight += this.DataGridView.Rows[i].Cells[this.ColumnIndex].Size.Height;

                // Determine the width before the current cell.
                nHeightTop = 0;
                for (i = m_nTopRow; i < RowIndex; i++)
                    nHeightTop += this.DataGridView.Rows[i].Cells[this.ColumnIndex].Size.Height;

                // Retrieve the text to be displayed
                strText = this.OwningRow.Cells[this.ColumnIndex].Value.ToString();
                cellBounds = new Rectangle(cellBounds.Left, cellBounds.Top - nHeightTop, cellBounds.Width, nHeight);
                cellState = selected ? DataGridViewElementStates.Selected : cellState;

                base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);
            }
            catch
            {

            }
        }

    }
    // class
    public class HeaderMergedGridViewTextBoxCell : DataGridViewColumnHeaderCell
    {
        private int m_nLeftColumn = 0;
        private int m_nRightColumn = 0;

        /// <summary>
        /// Column Index of the left-most cell to be merged.
        /// This cell controls the merged text.
        /// </summary>
        public int LeftColumn
        {
            get
            {
                return m_nLeftColumn;
            }
            set
            {
                m_nLeftColumn = value;
            }
        }

        /// <summary>
        /// Column Index of the right-most cell to be merged
        /// </summary>
        public int RightColumn
        {
            get
            {
                return m_nRightColumn;
            }
            set
            {
                m_nRightColumn = value;
            }
        }

        protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
        {
            try
            {
                int mergeindex = ColumnIndex - m_nLeftColumn;
                int i;
                int nWidth;
                int nWidthLeft;
                string strText;
                DataGridViewCellStyle style = this.HasStyle ? this.InheritedStyle : this.Style;
                GradContentPainter.DrawBackGroundHeaders(graphics, cellBounds, this.startgradColor, this.endgradColor);
                bool found = false;
                foreach (DataGridViewCell cell in this.DataGridView.SelectedCells)
                {
                    if ((cell.ColumnIndex >= m_nLeftColumn) && (cell.ColumnIndex <= m_nRightColumn))
                    {
                        found = true;
                        break;
                    }
                }
                if (!found)
                {
                    GradContentPainter.DrawBackGroundHeaders(graphics, cellBounds);
                }
                else
                {
                    GradContentPainter.DrawBackGroundHeaders(graphics, cellBounds, Color.FromArgb(248, 215, 151), Color.FromArgb(230, 241, 193, 95));
                }
                Color borderColor = this.DataGridView.GridColor;
                if (found)
                {
                    borderColor = Color.FromArgb(241, 180, 86);
                }
                // Draw the separator for rows
                graphics.DrawLine(new Pen(new SolidBrush(borderColor)), cellBounds.Left, cellBounds.Bottom - 1, cellBounds.Right, cellBounds.Bottom - 1);

                // Draw the right vertical line for the cell
                if (ColumnIndex == m_nRightColumn)
                    graphics.DrawLine(new Pen(new SolidBrush(borderColor)), cellBounds.Right - 1, cellBounds.Top, cellBounds.Right - 1, cellBounds.Bottom);

                // Draw the text
                RectangleF rectDest = RectangleF.Empty;

                // Determine the total width of the merged cell
                nWidth = 0;
                for (i = m_nLeftColumn; i <= m_nRightColumn; i++)
                    nWidth += this.DataGridView.Columns[i].HeaderCell.Size.Width;

                // Determine the width before the current cell.
                nWidthLeft = 0;
                for (i = m_nLeftColumn; i < ColumnIndex; i++)
                    nWidthLeft += this.DataGridView.Columns[i].HeaderCell.Size.Width;

                // Retrieve the text to be displayed
                strText = this.DataGridView.Columns[ColumnIndex].HeaderText;
                rectDest = new RectangleF(cellBounds.Left - nWidthLeft, cellBounds.Top, nWidth, cellBounds.Height);
                GradContentPainter.DrawContent(graphics, style, cellBounds, rectDest, strText, false);
            }
            catch
            {
                //Trace.WriteLine(ex.ToString());
            }
        }
        private Color endgradColor = Color.FromArgb(220, 220, 230);
        private Color startgradColor = Color.FromArgb(220, 230, 240);

    }// class
    public class GradDataGridViewTextBoxCell : DataGridViewTextBoxCell
    {
        protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
        {
            try
            {
                string strText;
                GradContentPainter.DrawBackGroundHeaders(graphics, cellBounds);

                // Draw the text
                RectangleF rectDest = RectangleF.Empty;
                StringFormat sf = new StringFormat();
                if (this.InheritedStyle.Alignment == DataGridViewContentAlignment.MiddleCenter)
                {
                    sf.LineAlignment = StringAlignment.Center;
                    sf.Alignment = StringAlignment.Center;
                }
                else if (this.InheritedStyle.Alignment == DataGridViewContentAlignment.MiddleLeft)
                {
                    sf.LineAlignment = StringAlignment.Center;
                    sf.Alignment = StringAlignment.Near;
                }
                else if (this.InheritedStyle.Alignment == DataGridViewContentAlignment.MiddleRight)
                {
                    sf.LineAlignment = StringAlignment.Center;
                    sf.Alignment = StringAlignment.Far;
                }
                else if (this.InheritedStyle.Alignment == DataGridViewContentAlignment.BottomCenter)
                {
                    sf.LineAlignment = StringAlignment.Far;
                    sf.Alignment = StringAlignment.Center;
                }
                else if (this.InheritedStyle.Alignment == DataGridViewContentAlignment.BottomLeft)
                {
                    sf.LineAlignment = StringAlignment.Far;
                    sf.Alignment = StringAlignment.Near;
                }
                else if (this.InheritedStyle.Alignment == DataGridViewContentAlignment.BottomRight)
                {
                    sf.LineAlignment = StringAlignment.Far;
                    sf.Alignment = StringAlignment.Far;
                }
                else if (this.InheritedStyle.Alignment == DataGridViewContentAlignment.TopCenter)
                {
                    sf.LineAlignment = StringAlignment.Near;
                    sf.Alignment = StringAlignment.Center;
                }
                else if (this.InheritedStyle.Alignment == DataGridViewContentAlignment.TopLeft)
                {
                    sf.LineAlignment = StringAlignment.Near;
                    sf.Alignment = StringAlignment.Near;
                }
                else if (this.InheritedStyle.Alignment == DataGridViewContentAlignment.TopRight)
                {
                    sf.LineAlignment = StringAlignment.Near;
                    sf.Alignment = StringAlignment.Far;
                }
                //this.PaintBorder(graphics, clipBounds, cellBounds, this.InheritedStyle,this.DataGridView.AdvancedCellBorderStyle);
                // Determine the total width of the merged cell
                GraphicsPath gph = new GraphicsPath();
                Pen p = new Pen(this.DataGridView.GridColor);
                gph.AddLine(cellBounds.X + cellBounds.Width - 1, cellBounds.Y, cellBounds.X + cellBounds.Width - 1, cellBounds.Y + cellBounds.Height - 1);
                gph.AddLine(cellBounds.X + cellBounds.Width - 1, cellBounds.Y + cellBounds.Height - 1, cellBounds.X, cellBounds.Y + cellBounds.Height - 1);
                graphics.DrawPath(p, gph);
                p.Dispose();
                // Retrieve the text to be displayed
                strText = this.FormattedValue.ToString();
                SolidBrush br = new SolidBrush(this.InheritedStyle.ForeColor);
                graphics.DrawString(strText, this.InheritedStyle.Font, br, cellBounds, sf);
                br.Dispose();
            }
            catch
            {
                //Trace.WriteLine(ex.ToString());
            }
        }
        private Color endgradColor = Color.FromArgb(220, 220, 230);

    }
    internal class GradContentPainter
    {
        private static Color startgradColor = Color.FromArgb(220, 230, 240);
        private static LinearGradientMode gradientMode = LinearGradientMode.Vertical;
        private static Color endgradColor = Color.FromArgb(220, 220, 230);
        private static float gradPercent = 0.5f;
        public static void DrawBackGroundHeaders(Graphics g, Rectangle rc, Color startGradColor, Color endGradColor)
        {

            // Create a rectangle
            //Rectangle rect = this.ClientRectangle;
            // Create a linear gradient brush
            SolidBrush br = new SolidBrush(Color.White);
            g.FillRectangle(br, rc);
            br.Dispose();
            LinearGradientBrush rgBrush = null;
            rgBrush = new LinearGradientBrush(
                   rc, startGradColor, endGradColor, gradientMode
                );
            // Set signma bell shape
            //rgBrush.SetSigmaBellShape(gradPercent, 1.0f);
            // Fill rectangle again
            g.FillRectangle(rgBrush, rc);
            // Dispose of object
            rgBrush.Dispose();
        }

        public static void DrawBackGroundHeaders(Graphics g, Rectangle rc)
        {
            DrawBackGroundHeaders(g, rc, startgradColor, startgradColor);
        }

        public static void DrawContent(Graphics graphics, DataGridViewCellStyle style, Rectangle cellBounds, RectangleF rectDest, string strText, bool Selected)
        {
            // Draw the text
            StringFormat sf = new StringFormat();
            if (style.Alignment == DataGridViewContentAlignment.MiddleCenter)
            {
                sf.LineAlignment = StringAlignment.Center;
                sf.Alignment = StringAlignment.Center;
            }
            else if (style.Alignment == DataGridViewContentAlignment.MiddleLeft)
            {
                sf.LineAlignment = StringAlignment.Center;
                sf.Alignment = StringAlignment.Near;
            }
            else if (style.Alignment == DataGridViewContentAlignment.MiddleRight)
            {
                sf.LineAlignment = StringAlignment.Center;
                sf.Alignment = StringAlignment.Far;
            }
            else if (style.Alignment == DataGridViewContentAlignment.BottomCenter)
            {
                sf.LineAlignment = StringAlignment.Far;
                sf.Alignment = StringAlignment.Center;
            }
            else if (style.Alignment == DataGridViewContentAlignment.BottomLeft)
            {
                sf.LineAlignment = StringAlignment.Far;
                sf.Alignment = StringAlignment.Near;
            }
            else if (style.Alignment == DataGridViewContentAlignment.BottomRight)
            {
                sf.LineAlignment = StringAlignment.Far;
                sf.Alignment = StringAlignment.Far;
            }
            else if (style.Alignment == DataGridViewContentAlignment.TopCenter)
            {
                sf.LineAlignment = StringAlignment.Near;
                sf.Alignment = StringAlignment.Center;
            }
            else if (style.Alignment == DataGridViewContentAlignment.TopLeft)
            {
                sf.LineAlignment = StringAlignment.Near;
                sf.Alignment = StringAlignment.Near;
            }
            else if (style.Alignment == DataGridViewContentAlignment.TopRight)
            {
                sf.LineAlignment = StringAlignment.Near;
                sf.Alignment = StringAlignment.Far;
            }


            // Retrieve the text to be displayed
            SolidBrush br = new SolidBrush(Selected ? style.SelectionForeColor : style.ForeColor);
            graphics.DrawString(strText, style.Font, br, rectDest, sf);
            br.Dispose();

        }
    }
    public class DataGridViewImageButtonCell : DataGridViewButtonCell
    {
        private bool _enabled;                // Is the button enabled
        private PushButtonState _buttonState; // What is the button state
        protected Image _buttonImageHot;      // The hot image
        protected Image _buttonImageNormal;   // The normal image
        protected Image _buttonImageDisabled; // The disabled image
        private int _buttonImageOffset;       // The amount of offset or border around the image

        public DataGridViewImageButtonCell()
        {
            // In my project, buttons are disabled by default
            _enabled = false;
            _buttonState = PushButtonState.Disabled;

            // Changing this value affects the appearance of the image on the button.
            _buttonImageOffset = 2;
        }

        // Button Enabled Property
        public bool Enabled
        {
            get
            {
                return _enabled;
            }

            set
            {
                _enabled = value;
                _buttonState = value ? PushButtonState.Normal : PushButtonState.Disabled;
            }
        }

        // PushButton State Property
        public PushButtonState ButtonState
        {
            get { return _buttonState; }
            set { _buttonState = value; }
        }

        // Image Property
        // Returns the correct image based on the control's state.
        public Image ButtonImage
        {
            get
            {
                switch (_buttonState)
                {
                    case PushButtonState.Disabled:
                        return _buttonImageDisabled;

                    case PushButtonState.Hot:
                        return _buttonImageHot;

                    case PushButtonState.Normal:
                        return _buttonImageNormal;

                    case PushButtonState.Pressed:
                        return _buttonImageNormal;

                    case PushButtonState.Default:
                        return _buttonImageNormal;
                    default:
                        return _buttonImageNormal;
                }
            }
        }

        protected override void Paint(Graphics graphics,
            Rectangle clipBounds, Rectangle cellBounds, int rowIndex,
            DataGridViewElementStates elementState, object value,
            object formattedValue, string errorText,
            DataGridViewCellStyle cellStyle,
            DataGridViewAdvancedBorderStyle advancedBorderStyle,
            DataGridViewPaintParts paintParts)
        {
            //base.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);

            // Draw the cell background, if specified.
            if ((paintParts & DataGridViewPaintParts.Background) ==
                DataGridViewPaintParts.Background)
            {
                SolidBrush cellBackground =
                    new SolidBrush(cellStyle.BackColor);
                graphics.FillRectangle(cellBackground, cellBounds);
                cellBackground.Dispose();
            }

            // Draw the cell borders, if specified.
            if ((paintParts & DataGridViewPaintParts.Border) ==
                DataGridViewPaintParts.Border)
            {
                PaintBorder(graphics, clipBounds, cellBounds, cellStyle,
                    advancedBorderStyle);
            }

            // Calculate the area in which to draw the button.
            // Adjusting the following algorithm and values affects
            // how the image will appear on the button.
            Rectangle buttonArea = cellBounds;

            Rectangle buttonAdjustment =
                BorderWidths(advancedBorderStyle);

            buttonArea.X += buttonAdjustment.X;
            buttonArea.Y += buttonAdjustment.Y;
            buttonArea.Height -= buttonAdjustment.Height;
            buttonArea.Width -= buttonAdjustment.Width;

            Rectangle imageArea = new Rectangle(
                buttonArea.X + _buttonImageOffset,
                buttonArea.Y + _buttonImageOffset,
                16,
                16);
            Image image = ButtonImage;
            Font font = new Font("Arial", 8f);
            string st = "";
            if (value != null)
                st = value.ToString();
            if (image != null)
            {
                ButtonRenderer.DrawButton(graphics, buttonArea, st, font, TextFormatFlags.Bottom, image, imageArea, false, ButtonState);
            }
            else
            {
                ButtonRenderer.DrawButton(graphics, buttonArea, st, font, false, ButtonState);
            }
        }

        // An abstract method that must be created in each derived class.
        // The images in the derived class will be loaded here.
        public void Set_buttonImageHot(Image image)
        {
            _buttonImageHot = image;
        }
        public void Set_buttonImageNormal(Image image)
        {
            _buttonImageNormal = image;
        }
        public void Set_buttonImageDisabled(Image image)
        {
            _buttonImageDisabled = image;
        }

    }
    public class DataGridViewImageButtonColumn : DataGridViewButtonColumn
    {
        public DataGridViewImageButtonColumn()
        {
            this.CellTemplate = new DataGridViewImageButtonCell();
            this.Width = 22;
            this.Resizable = DataGridViewTriState.False;
        }
    }

    public class CalendarColumn : DataGridViewColumn
    {
        public CalendarColumn()
            : base(new CalendarCell())
        {
        }

        public override DataGridViewCell CellTemplate
        {
            get
            {
                return base.CellTemplate;
            }
            set
            {
                // Ensure that the cell used for the template is a CalendarCell.
                if (value != null &&
                    !value.GetType().IsAssignableFrom(typeof(CalendarCell)))
                {
                    throw new InvalidCastException("Must be a CalendarCell");
                }
                base.CellTemplate = value;
            }
        }
    }

    public class CalendarCell : DataGridViewTextBoxCell
    {

        public CalendarCell()
            : base()
        {
            // Use the short date format.

        }

        public override void InitializeEditingControl(int rowIndex, object
            initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
        {
            // Set the value of the editing control to the current cell value.
            base.InitializeEditingControl(rowIndex, initialFormattedValue,
                dataGridViewCellStyle);
            CalendarEditingControl ctl =
                DataGridView.EditingControl as CalendarEditingControl;

            ctl.EditingControlDataGridView = base.DataGridView;
            if (DataGridView.Columns[this.ColumnIndex].DefaultCellStyle.Format != "")
            {
                ctl.Format = DateTimePickerFormat.Custom;
                ctl.CustomFormat = DataGridView.Columns[this.ColumnIndex].DefaultCellStyle.Format;
            }
            if (this.Value is DateTime)
                ctl.Value = (DateTime)this.Value;
        }

        public override Type EditType
        {
            get
            {
                // Return the type of the editing contol that CalendarCell uses.
                return typeof(CalendarEditingControl);
            }
        }

        public override Type ValueType
        {
            get
            {
                // Return the type of the value that CalendarCell contains.
                return typeof(DateTime);
            }
        }
        protected override object GetFormattedValue(object value, int rowIndex, ref DataGridViewCellStyle cellStyle, System.ComponentModel.TypeConverter valueTypeConverter, System.ComponentModel.TypeConverter formattedValueTypeConverter, DataGridViewDataErrorContexts context)
        {
            if (DataGridView.Columns[this.ColumnIndex].DefaultCellStyle.Format != "")
            {
                cellStyle.Format = DataGridView.Columns[this.ColumnIndex].DefaultCellStyle.Format;
            }
            return base.GetFormattedValue(value, rowIndex, ref cellStyle, valueTypeConverter, formattedValueTypeConverter, context);
        }

        public override object DefaultNewRowValue
        {
            get
            {
                // Use the current date and time as the default value.
                return DateTime.Now;
            }
        }

    }

    public class CalendarEditingControl : DateTimePicker, IDataGridViewEditingControl
    {
        System.Windows.Forms.DataGridView dataGridView;
        private bool valueChanged = false;
        int rowIndex;

        public CalendarEditingControl()
        {
            this.Format = DateTimePickerFormat.Short;
        }

        // Implements the IDataGridViewEditingControl.EditingControlFormattedValue 
        // property.
        public object EditingControlFormattedValue
        {
            get
            {
                return this.Value.ToShortDateString();
            }
            set
            {
                if (value is String)
                {
                    this.Value = DateTime.Parse((String)value);
                }
            }
        }

        // Implements the 
        // IDataGridViewEditingControl.GetEditingControlFormattedValue method.
        public object GetEditingControlFormattedValue(
            DataGridViewDataErrorContexts context)
        {
            return EditingControlFormattedValue;
        }

        // Implements the 
        // IDataGridViewEditingControl.ApplyCellStyleToEditingControl method.
        public void ApplyCellStyleToEditingControl(
            DataGridViewCellStyle dataGridViewCellStyle)
        {
            this.Font = dataGridViewCellStyle.Font;
            this.CalendarForeColor = dataGridViewCellStyle.ForeColor;
            this.CalendarMonthBackground = dataGridViewCellStyle.BackColor;
        }

        // Implements the IDataGridViewEditingControl.EditingControlRowIndex 
        // property.
        public int EditingControlRowIndex
        {
            get
            {
                return rowIndex;
            }
            set
            {
                rowIndex = value;
            }
        }

        // Implements the IDataGridViewEditingControl.EditingControlWantsInputKey 
        // method.
        public bool EditingControlWantsInputKey(
            Keys key, bool dataGridViewWantsInputKey)
        {
            // Let the DateTimePicker handle the keys listed.
            switch (key & Keys.KeyCode)
            {
                case Keys.Left:
                case Keys.Up:
                case Keys.Down:
                case Keys.Right:
                case Keys.Home:
                case Keys.End:
                case Keys.PageDown:
                case Keys.PageUp:
                    return true;
                default:
                    return false;
            }
        }

        // Implements the IDataGridViewEditingControl.PrepareEditingControlForEdit 
        // method.
        public void PrepareEditingControlForEdit(bool selectAll)
        {
            // No preparation needs to be done.
        }

        // Implements the IDataGridViewEditingControl
        // .RepositionEditingControlOnValueChange property.
        public bool RepositionEditingControlOnValueChange
        {
            get
            {
                return false;
            }
        }

        // Implements the IDataGridViewEditingControl
        // .EditingControlDataGridView property.
        public System.Windows.Forms.DataGridView EditingControlDataGridView
        {
            get
            {
                return dataGridView;
            }
            set
            {
                dataGridView = value;
            }
        }

        // Implements the IDataGridViewEditingControl
        // .EditingControlValueChanged property.
        public bool EditingControlValueChanged
        {
            get
            {
                return valueChanged;
            }
            set
            {
                valueChanged = value;
            }
        }

        // Implements the IDataGridViewEditingControl
        // .EditingPanelCursor property.
        public Cursor EditingPanelCursor
        {
            get
            {
                return base.Cursor;
            }
        }

        protected override void OnValueChanged(EventArgs eventargs)
        {
            // Notify the DataGridView that the contents of the cell
            // have changed.
            valueChanged = true;
            this.EditingControlDataGridView.NotifyCurrentCellDirty(true);
            base.OnValueChanged(eventargs);
        }



        #region IDataGridViewEditingControl Members

        private System.Windows.Forms.DataGridView grid = null;
        System.Windows.Forms.DataGridView IDataGridViewEditingControl.EditingControlDataGridView
        {
            get
            {
                return grid;
            }
            set
            {
                grid = value;
            }
        }

        #endregion
    }
    public class GridNodeItem
    {
        public GridNodeItem()
        {
            BackGroundColor = Color.Yellow;
            TitleColor = Color.Red;
            TextColor = Color.Blue;
        }
        public string Title { set; get; }
        public string Content { set; get; }
        public Image Icon { set; get; }
        public Color BackGroundColor { get; set; }
        public Color TextColor { get; set; }
        public Color TitleColor { get; set; }
    }

}
